package test2;

import org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator;
import org.springframework.boot.autoconfigure.aop.AopAutoConfiguration;
import org.springframework.context.annotation.AnnotationConfigUtils;
import org.springframework.context.annotation.ConfigurationClassPostProcessor;
import org.springframework.context.annotation.DeferredImportSelector;
import org.springframework.context.annotation.Import;
import org.springframework.context.support.GenericApplicationContext;
import org.springframework.core.env.SimpleCommandLinePropertySource;
import org.springframework.core.env.StandardEnvironment;
import org.springframework.core.type.AnnotationMetadata;

/**
 * @author: mornd
 * @dateTime: 2023/5/11 - 14:18
 * aop 自动配置原理
 */
public class App {
    public static void main(String[] args) {
        GenericApplicationContext context = new GenericApplicationContext();

        StandardEnvironment env = new StandardEnvironment();
        env.getPropertySources().addLast(new SimpleCommandLinePropertySource("--spring.aop.auto=true"));
        context.setEnvironment(env);

        /*
        internalAutowiredAnnotationProcessor
            处理 @Autowired @Value 注解
        internalCommonAnnotationProcessor
            处理 @Resource @PostConstructor @PostDestroy
        ConfigurationClassPostProcessor
            处理 @Configuration @Bean @Import @componentScan
         */
        AnnotationConfigUtils.registerAnnotationConfigProcessors(context.getDefaultListableBeanFactory());
        context.registerBean(Config.class);

        context.refresh();

        for (String name : context.getBeanDefinitionNames()) {
            System.out.println(name);
        }

        // 前提导入 aspectj 依赖
        // 将代理创建器加入到容器中
        AnnotationAwareAspectJAutoProxyCreator bean =
                context.getBean("org.springframework.aop.config.internalAutoProxyCreator",
                AnnotationAwareAspectJAutoProxyCreator.class);
        System.out.println(bean.isProxyTargetClass());

        context.close();
    }

    @Import(MyImportSelector.class)
    static class Config {

    }

    static class MyImportSelector implements DeferredImportSelector {

        @Override
        public String[] selectImports(AnnotationMetadata importingClassMetadata) {
            return new String[] {AopAutoConfiguration.class.getName()};
        }
    }
}
